'''
字符串的定义和使用
字符串是 Python 中最常用的数据类型，我们可以使用单引号、双引号或三引号来定义字符串。
'''
s1 = 'hello, world!'
s2 = "你好，世界！❤️"
s3 = '''hello,
wonderful
world!'''
print(s1)
print(s2)
print(s3)
'''
字符串的转义字符
在字符串中，我们可以使用反斜杠（\）来表示转义字符，例如：
\n 表示换行
\t 表示制表符
\\ 表示反斜杠
\' 表示单引号
\" 表示双引号
\r 表示回车
\b 表示退格
\f 表示换页
\v 表示垂直制表符
\a 表示报警
\0 表示空字符

'''
s1 = '\'hello, world!\''
s2 = '\\hello, world!\\'
print(s1)
print(s2)
'''
原始字符串
在字符串中，我们可以使用反斜杠（\）来表示转义字符，例如：
\n 表示换行
\t 表示制表符
\\ 表示反斜杠
\' 表示单引号
\" 表示双引号
\r 表示回车
\b 表示退格
\f 表示换页
\v 表示垂直制表符
\a 表示报警
\0 表示空字符

'''
s1 = '\it \is \time \to \read \now'
s2 = r'\it \is \time \to \read \now'
print(s1)
print(s2)
'''
字符串的编码
在 Python 中，字符串是 Unicode 字符串，每个字符占用 2 个字节。
我们可以使用 ord() 函数来获取字符的 Unicode 编码，使用 chr() 函数来获取 Unicode 编码对应的字符。

'''
s1 = '\141\142\143\x61\x62\x63'
s2 = '\u9a86\u660a'
print(s1)
print(s2)
'''
使用+和*运算符来实现字符串的拼接和重复操作。
'''
s1 = 'hello' + ', ' + 'world'
print(s1)    # hello, world
s2 = '!' * 3
print(s2)    # !!!
s1 += s2
print(s1)    # hello, world!!!
s1 *= 2
print(s1)    # hello, world!!!hello, world!!!
'''
字符串的比较
我们可以使用比较运算符（==、!=、<、>、<=、>=）来比较字符串的大小。
比较的规则是：先比较第一个字符的 Unicode 编码，如果相等，再比较第二个字符的 Unicode 编码，以此类推。
'''
s1 = 'a whole new world'
s2 = 'hello world'
print(s1 == s2)             # False
print(s1 < s2)              # True
print(s1 == 'hello world')  # False
print(s2 == 'hello world')  # True
print(s2 != 'Hello world')  # True
s3 = '骆昊'
print(ord('骆'))            # 39558
print(ord('昊'))            # 26122
s4 = '王大锤'
print(ord('王'))            # 29579
print(ord('大'))            # 22823
print(ord('锤'))            # 38180
print(s3 >= s4)             # True
print(s3 != s4)             # True
'''
成员运算
'''
s1 = 'hello, world'
s2 = 'goodbye, world'
print('wo' in s1)      # True
print('wo' not in s2)  # False
print(s2 in s1)        # False
'''
字符串的索引和切片
字符串的索引和切片操作与列表的索引和切片操作相同，都是使用方括号（[]）来实现的。
'''
s = 'abc123456'
n = len(s)
print(s[0], s[-n])    # a a
print(s[n-1], s[-1])  # 6 6
print(s[2], s[-7])    # c c
print(s[5], s[-4])    # 3 3
print(s[2:5])         # c12
print(s[-7:-4])       # c12
print(s[2:])          # c123456
print(s[:2])          # ab
print(s[::2])         # ac246
print(s[::-1])        # 654321cba

'''
字符串的方法
'''
s1 = 'hello, world!'
# 字符串首字母大写
print(s1.capitalize())  # Hello, world!
# 字符串每个单词首字母大写
print(s1.title())       # Hello, World!
# 字符串变大写
print(s1.upper())       # HELLO, WORLD!
s2 = 'GOODBYE'
# 字符串变小写
print(s2.lower())       # goodbye
# 检查s1和s2的值
print(s1)               # hello, world
print(s2)               # GOODBYE
'''
字符串的查找
'''
s = 'hello, world!'
print(s.find('or'))      # 8
print(s.find('or', 9))   # -1
print(s.find('of'))      # -1
print(s.index('or'))     # 8
print(s.index('or', 9))  # ValueError: substring not found

print(s.find('o'))       # 4
print(s.rfind('o'))      # 7
print(s.rindex('o'))     # 7

'''
字符串的startswith、endswith来判断字符串是否以某个字符串开头和结尾；还可以用is开头的方法判断字符串的特征，这些方法都返回布尔值
isdigit用来判断字符串是不是完全由数字构成的，
isalpha用来判断字符串是不是完全由字母构成的，这里的字母指的是 Unicode 字符但不包含 Emoji 字符，
isalnum用来判断字符串是不是由字母和数字构成的。
'''
s1 = 'hello, world!'
print(s1.startswith('He'))   # False
print(s1.startswith('hel'))  # True
print(s1.endswith('!'))      # True
s2 = 'abc123456'
print(s2.isdigit())  # False
print(s2.isalpha())  # False
print(s2.isalnum())  # True
'''
在 Python 中，字符串类型可以通过center、ljust、rjust方法做居中、左对齐和右对齐的处理。如果要在字符串的左侧补零，也可以使用zfill方法。
'''
s = 'hello, world'
print(s.center(20, '*'))  # ****hello, world****
print(s.rjust(20))        #         hello, world
print(s.ljust(20, '~'))   # hello, world~~~~~~~~
print('33'.zfill(5))      # 00033
print('-33'.zfill(5))     # -0033
'''
在 Python 中，字符串类型可以通过center、ljust、rjust方法做居中、左对齐和右对齐的处理。如果要在字符串的左侧补零，也可以使用zfill方法。
'''
s = 'hello, world'
print(s.center(20, '*'))  # ****hello, world****
print(s.rjust(20))        #         hello, world
print(s.ljust(20, '~'))   # hello, world~~~~~~~~
print('33'.zfill(5))      # 00033
print('-33'.zfill(5))     # -0033
'''
我们之前讲过，在用print函数输出字符串时，可以用下面的方式对字符串进行格式化。
'''
a = 321
b = 123
print('%d * %d = %d' % (a, b, a * b))
'''
当然，我们也可以用字符串的format方法来完成字符串的格式，代码如下所示。
'''
a = 321
b = 123
print('{0} * {1} = {2}'.format(a, b, a * b))
'''
从 Python 3.6 开始，格式化字符串还有更为简洁的书写方式，就是在字符串前加上f来格式化字符串，在这种以f打头的字符串中，{变量名}是一个占位符，会被变量对应的值将其替换掉，代码如下所示。
'''
a = 321
b = 123
print(f'{a} * {b} = {a * b}')
'''
如果需要进一步控制格式化语法中变量值的形式，可以参照下面的表格来进行字符串格式化操作。

变量值	占位符	格式化结果	说明
3.1415926	{:.2f}	'3.14'	保留小数点后两位
3.1415926	{:+.2f}	'+3.14'	带符号保留小数点后两位
-1	{:+.2f}	'-1.00'	带符号保留小数点后两位
3.1415926	{:.0f}	'3'	不带小数
123	{:0>10d}	'0000000123'	左边补0，补够10位
123	{:x<10d}	'123xxxxxxx'	右边补x ，补够10位
123	{:>10d}	' 123'	左边补空格，补够10位
123	{:<10d}	'123 '	右边补空格，补够10位
123456789	{:,}	'123,456,789'	逗号分隔格式
0.123	{:.2%}	'12.30%'	百分比格式
123456789	{:.2e}	'1.23e+08'	科学计数法格式
'''

'''
字符串的strip方法可以帮我们获得将原字符串修剪掉左右两端指定字符之后的字符串，默认是修剪空格字符。这个方法非常有实用价值，可以用来将用户输入时不小心键入的头尾空格等去掉，strip方法还有lstrip和rstrip两个版本，相信从名字大家已经猜出来这两个方法是做什么用的。
'''
s1 = '   jackfrued@126.com  '
print(s1.strip())      # jackfrued@126.com
s2 = '~你好，世界~'
print(s2.lstrip('~'))  # 你好，世界~
print(s2.rstrip('~'))  # ~你好，世界
'''
如果希望用新的内容替换字符串中指定的内容，可以使用replace方法，代码如下所示。replace方法的第一个参数是被替换的内容，第二个参数是替换后的内容，还可以通过第三个参数指定替换的次数。
'''
s = 'hello, good world'
print(s.replace('o', '@'))     # hell@, g@@d w@rld
print(s.replace('o', '@', 1))  # hell@, good world
'''
可以使用字符串的split方法将一个字符串拆分为多个字符串（放在一个列表中），也可以使用字符串的join方法将列表中的多个字符串连接成一个字符串，代码如下所示。
'''
s = 'I love you'
words = s.split()
print(words)            # ['I', 'love', 'you']
print('~'.join(words))  # I~love~you
'''
需要说明的是，split方法默认使用空格进行拆分，我们也可以指定其他的字符来拆分字符串，而且还可以指定最大拆分次数来控制拆分的效果，代码如下所示。
'''
s = 'I#love#you#so#much'
words = s.split('#')
print(words)  # ['I', 'love', 'you', 'so', 'much']
words = s.split('#', 2)
print(words)  # ['I', 'love', 'you#so#much']
'''
Python 中除了字符串str类型外，还有一种表示二进制数据的字节串类型（bytes）。所谓字节串，就是由零个或多个字节组成的有限序列。通过字符串的encode方法，我们可以按照某种编码方式将字符串编码为字节串，我们也可以使用字节串的decode方法，将字节串解码为字符串，代码如下所示。
'''
a = '骆昊'
b = a.encode('utf-8')
c = a.encode('gbk')
print(b)                  # b'\xe9\xaa\x86\xe6\x98\x8a'
print(c)                  # b'\xc2\xe6\xea\xbb'
print(b.decode('utf-8'))  # 骆昊
print(c.decode('gbk'))    # 骆昊